﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using Classified.Data.Repositories;
using Classified.Domain.Entities;
using Classified.Service;
using Classified.Web.Helpers;
using Classified.Web.Models;
using Classified.Web.Services;

namespace Classified.Web.Controllers
{
    public class AccountController : Controller
    {
        private readonly ISecurityService _securityService;
        public IFormsAuthenticationService AuthenticationService { get; set; }
        public IQueuedEmailRepositories _QueuedEmailRepositories { get; set; }
        public IEmailVerificationlLogRepositories _VerificationlLogRepositories { get; set; }

        private readonly string cookieDomainName = ConfigurationManager.AppSettings["cookieDomainName"];
        private readonly string AdminEmail = ConfigurationManager.AppSettings["AdminMail"];
        private readonly string EmailFrom = ConfigurationManager.AppSettings["EmailFrom"];
        public AccountController(ISecurityService securityService, IEmailVerificationlLogRepositories verificationlLogRepositories, IQueuedEmailRepositories queuedEmailRepositories)
        {
            _securityService = securityService;
            AuthenticationService = new FormsAuthenticationService(new HttpContextWrapper(System.Web.HttpContext.Current));
            _QueuedEmailRepositories = queuedEmailRepositories;
            _VerificationlLogRepositories = verificationlLogRepositories;
        }
        //
        // GET: /Account/LogOn

        public ActionResult LogOn()
        {
            return View();
        }

        //
        // POST: /Account/LogOn
        public ActionResult LostPassword()
        {
           
            return View();
        }
        [HttpPost]
        public ActionResult LostPassword(LostPassword model)
        {
            
            var user = _securityService.GetUserByEmailId(model.Email);
            if (user != null)
            {
                var password = CryptorEngine.Decrypt(user.Password, true);
                var body = "OLX Free Classifieds<br/><br/> Below is the login information you requested.<br/>";
                body += "User name :" + user.UserName + "<br/> Password :" + password + "Thank you for using Adsx24,<br/>The Adsx24 Team ";
                var objQueuedEmail = new QueuedEmail();
                bool emailSendStatus = false;
                emailSendStatus = EmailHelper.SendEmail(AdminEmail, model.Email,
                                                        "Your Lost Login Information",
                                                        body, EmailFrom);


                if (!emailSendStatus)
                {
                    objQueuedEmail.SentOnUtc = DateTime.UtcNow;
                    objQueuedEmail.To = model.Email;
                    objQueuedEmail.From = AdminEmail;
                    objQueuedEmail.Body = body;
                    objQueuedEmail.CreatedOnUtc = DateTime.UtcNow;
                    objQueuedEmail.FromName = EmailFrom;
                    objQueuedEmail.SentTries = 0;
                    objQueuedEmail.Subject = "Your Lost Login Information";
                    objQueuedEmail.IsSent = false;
                    _QueuedEmailRepositories.Add(objQueuedEmail);
                }
                return Content(" <i class='icon-ok></i> Your password has been emailed to you.");
            }
            return Content("<i class='icon-remove'></i> There is no password set for this email address on Adsx24. Feel free to register with Adsx24.");
        }
        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl, FormCollection fm)
        {

            if (ModelState.IsValid)
            {
                var password = CryptorEngine.Encrypt(model.Password, true);
                var user = _securityService.CheckLogin(model.UserName, password);

                if (user != null)
                {
                    AuthenticationService.SignIn(user, model.RememberMe);
                    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                    {
                        return Redirect(returnUrl);
                    }
                    return RedirectToAction("Index", "Home");
                }
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }

            // If we got this far, something failed, redisplay form
            return View(model);

            //if (ModelState.IsValid)
            //{
            //    if (Membership.ValidateUser(model.UserName, model.Password))
            //    {
            //        FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
            //        if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
            //            && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
            //        {
            //            return Redirect(returnUrl);
            //        }
            //        else
            //        {
            //            return RedirectToAction("Index", "Home");
            //        }
            //    }
            //    else
            //    {
            //        ModelState.AddModelError("", "The user name or password provided is incorrect.");
            //    }
            //}

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/LogOff

        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();

            return RedirectToAction("Index", "Home");
        }

        //
        // GET: /Account/Register
        [Authorize]
        public ActionResult SelectPassword()
        {
            var username = User.Identity.Name;
            var user = _securityService.GetUserByName(username);
            var reg = new RegisterModel();
            reg.Email = user.Email;

            return View(reg);
        }
        [HttpPost]
        public ActionResult SelectPassword(RegisterModel model)
        {
            if (_securityService.IsUserNameAvailabel(model.UserName))
            {
                var user = new User()
                {
                    DateCreated = DateTime.UtcNow,
                    DateLastActivity = DateTime.UtcNow,
                    DateLastLogin = DateTime.UtcNow,
                    DateLastPasswordChange = DateTime.UtcNow,
                    Email = model.Email,
                    FirstName = model.UserName,
                    LastName = model.UserName,
                    UserName = model.UserName,
                    Password = CryptorEngine.Encrypt(model.Password, true),
                    IsActive = true,
                };
                _securityService.CreateUser(user);
                FormsAuthentication.SignOut();
                _securityService.CheckLogin(user.UserName, user.Password);
                AuthenticationService.SignIn(user, false);
                var objQueuedEmail = new QueuedEmail();
                bool emailSendStatus = false;
                emailSendStatus = EmailHelper.SendEmail(AdminEmail, model.Email, "Thank You for Registration",
                                                        "Thank You for Registration", EmailFrom);


                if (!emailSendStatus)
                {
                    objQueuedEmail.SentOnUtc = DateTime.UtcNow;
                    objQueuedEmail.To = model.Email;
                    objQueuedEmail.From = AdminEmail;
                    objQueuedEmail.Body = "Thank You for Registration";
                    objQueuedEmail.CreatedOnUtc = DateTime.UtcNow;
                    objQueuedEmail.FromName = EmailFrom;
                    objQueuedEmail.SentTries = 0;
                    objQueuedEmail.Subject = "Thank You for Registration";
                    objQueuedEmail.IsSent = false;
                    _QueuedEmailRepositories.Add(objQueuedEmail);
                }

                return RedirectToAction("MyAds", "Home");
            }
            return View(model);
        }

        public ActionResult Register()
        {

            return View();
        }

        //
        // POST: /Account/Register

        [HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                //  MembershipCreateStatus createStatus;
                //  Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);
                if (_securityService.IsUserNameAvailabel(model.UserName))
                {
                    if (_securityService.IsEmailIDAvailabel(model.Email))
                    {


                        var user = new User()
                                       {
                                           DateCreated = DateTime.UtcNow,
                                           DateLastActivity = DateTime.UtcNow,
                                           DateLastLogin = DateTime.UtcNow,
                                           DateLastPasswordChange = DateTime.UtcNow,
                                           Email = model.Email,
                                           FirstName = model.UserName,
                                           LastName = model.UserName,
                                           UserName = model.UserName,
                                           Password = CryptorEngine.Encrypt(model.Password, true),
                                           IsActive = true,
                                       };
                        _securityService.CreateUser(user);
                        AuthenticationService.SignIn(user, false);
                        //FormsAuthentication.SetAuthCookie(model.UserName, false /* createPersistentCookie */);
                        var objQueuedEmail = new QueuedEmail();
                        bool emailSendStatus = false;
                        emailSendStatus = EmailHelper.SendEmail(AdminEmail, model.Email, "Thank You for Registration",
                                                                "Thank You for Registration", EmailFrom);


                        if (!emailSendStatus)
                        {
                            objQueuedEmail.SentOnUtc = DateTime.UtcNow;
                            objQueuedEmail.To = model.Email;
                            objQueuedEmail.From = AdminEmail;
                            objQueuedEmail.Body = "Thank You for Registration";
                            objQueuedEmail.CreatedOnUtc = DateTime.UtcNow;
                            objQueuedEmail.FromName = EmailFrom;
                            objQueuedEmail.SentTries = 0;
                            objQueuedEmail.Subject = "Thank You for Registration";
                            objQueuedEmail.IsSent = false;
                            _QueuedEmailRepositories.Add(objQueuedEmail);
                        }

                        return RedirectToAction("Index", "Home");
                    }

                    else
                    {
                        ModelState.AddModelError("Email", ErrorCodeToString(MembershipCreateStatus.DuplicateUserName));
                    }


                }

                else
                {
                    ModelState.AddModelError("UserName", ErrorCodeToString(MembershipCreateStatus.DuplicateUserName));
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/ChangePassword

        //
        // POST: /Account/ChangePassword
        public ActionResult ChangePassword()
        {
            return View();
        }
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            var username = User.Identity.Name;
            var user = _securityService.GetUserByName(username);
            if (user != null)
            {
                var password = CryptorEngine.Encrypt(model.OldPassword, true);
                if (user.Password == password)
                {

                    if (model.NewPassword.Length > 3)
                    {
                        user.Password = CryptorEngine.Encrypt(model.NewPassword, true);

                        _securityService.UpdateUser(user);
                        return RedirectToAction("ChangePasswordSuccess");
                    }
                }
            }

            return View(model);
        }

        //
        // GET: /Account/ChangePasswordSuccess

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        public ActionResult MyProfile()
        {
            var usename = User.Identity.Name;
            var data = _securityService.GetUserByName(usename);
            return View(data);
        }

        public ActionResult EditProfile()
        {
            var usename = User.Identity.Name;
            var data = _securityService.GetUserByName(usename);
            return View(data);
        }


        [HttpPost]
        public ActionResult EditProfile(User model)
        {
            if (ModelState.IsValid)
            {
                var user = _securityService.GetUserById(model.Id);
                if (user.UserName == model.UserName && user.Email == model.Email)
                {
                    if (_securityService.IsUserNameAvailabel(model.UserName) && _securityService.IsEmailIDAvailabel(model.Email))
                    {



                        user.FirstName = model.FirstName;
                        user.LastName = model.LastName;
                        user.UserName = model.UserName;
                        user.Email = model.Email;
                        _securityService.UpdateUser(user);
                        FormsAuthentication.SignOut();
                        _securityService.CheckLogin(user.UserName, user.Password);
                        AuthenticationService.SignIn(user, false);
                        return RedirectToAction("MyAds", "Home");

                    }
                    else
                    {
                        if (_securityService.IsEmailIDAvailabel(model.Email) == false && _securityService.IsUserNameAvailabel(model.UserName))
                        {
                            ModelState.AddModelError("Email", ErrorCodeToString(MembershipCreateStatus.DuplicateEmail));
                            return View(model);
                        }
                        else if (_securityService.IsUserNameAvailabel(model.UserName) == false && _securityService.IsEmailIDAvailabel(model.Email))
                        {
                            ModelState.AddModelError("Username", ErrorCodeToString(MembershipCreateStatus.DuplicateUserName));
                            return View(model);
                        }
                        else
                        {
                            ModelState.AddModelError("Email", ErrorCodeToString(MembershipCreateStatus.DuplicateEmail));
                            ModelState.AddModelError("Username", ErrorCodeToString(MembershipCreateStatus.DuplicateUserName));
                            return View(model);
                        }
                    }
                }
                else if (model.Email == user.Email && model.UserName != user.UserName)
                {
                    if (_securityService.IsUserNameAvailabel(model.UserName))
                    {
                        user.FirstName = model.FirstName;
                        user.LastName = model.LastName;
                        user.UserName = model.UserName;
                        user.Email = model.Email;
                        _securityService.UpdateUser(user);
                        FormsAuthentication.SignOut();
                        _securityService.CheckLogin(user.UserName, user.Password);
                        AuthenticationService.SignIn(user, false);
                        return RedirectToAction("MyAds", "Home");
                    }
                    else
                    {
                        ModelState.AddModelError("Username", ErrorCodeToString(MembershipCreateStatus.DuplicateUserName));
                        return View(model);
                    }
                }
                else if (model.Email != user.Email && model.UserName == user.UserName)
                {
                    if (_securityService.IsEmailIDAvailabel(model.Email))
                    {
                        user.FirstName = model.FirstName;
                        user.LastName = model.LastName;
                        user.UserName = model.UserName;
                        user.Email = model.Email;
                        _securityService.UpdateUser(user);
                        FormsAuthentication.SignOut();
                        _securityService.CheckLogin(user.UserName, user.Password);
                        AuthenticationService.SignIn(user, false);
                        return RedirectToAction("MyAds", "Home");

                    }
                    else
                    {
                        ModelState.AddModelError("Email", ErrorCodeToString(MembershipCreateStatus.DuplicateEmail));
                        return View(model);
                    }
                }
                else
                {
                    user.FirstName = model.FirstName;
                    user.LastName = model.LastName;
                    user.UserName = model.UserName;
                    user.Email = model.Email;
                    _securityService.UpdateUser(user);
                    FormsAuthentication.SignOut();
                    _securityService.CheckLogin(user.UserName, user.Password);
                    AuthenticationService.SignIn(user, false);
                    return RedirectToAction("MyAds", "Home");

                }
            }
            return View(model);
        }
        [HttpPost]
        public ActionResult LogOnByEmail(User Model)
        {
            var guid = Guid.NewGuid().ToString();

            var chk_user = _securityService.GetUserByEmailId(Model.Email);
            if (chk_user != null)
            {
                var verified = _VerificationlLogRepositories.GetById(x => x.UserId == chk_user.Id);
                if (verified != null)
                {
                    guid = verified.VerifiedId;
                }
                else
                {
                    var ver_log = new EmailVerificationlLog()
                                      {
                                          UserId = chk_user.Id,
                                          VerifiedId = guid,
                                          CreateDate = DateTime.UtcNow
                                      };
                    _VerificationlLogRepositories.Add(ver_log);

                }
            }


            var body =
                "<h1>PLEASE KEEP THIS EMAIL Do not forward it to anyone.</h1><br/>You can use the links below to manage your ad.<br/><br/><h3>MANAGE YOUR AD (EDIT, DELETE, ADD PICTURES):</h3><br/>";

            body += "http://"+cookieDomainName+"/myadsindex?UN=" + guid;

            body += "<br/><br/> Thank you for using Adsx24,<br/> <b>The Adsx24 Team</b> ";
            var objQueuedEmail = new QueuedEmail();
            bool emailSendStatus = false;
            emailSendStatus = EmailHelper.SendEmail(AdminEmail, Model.Email, "Adsx24 Manage your ads - Access your account",
                                                    body, EmailFrom);


            if (!emailSendStatus)
            {
                objQueuedEmail.SentOnUtc = DateTime.UtcNow;
                objQueuedEmail.To = Model.Email;
                objQueuedEmail.From = AdminEmail;
                objQueuedEmail.Body = body;
                objQueuedEmail.CreatedOnUtc = DateTime.UtcNow;
                objQueuedEmail.FromName = EmailFrom;
                objQueuedEmail.SentTries = 0;
                objQueuedEmail.Subject = "Adsx24 Manage your ads - Access your account";
                objQueuedEmail.IsSent = false;
                _QueuedEmailRepositories.Add(objQueuedEmail);
            }
            if (_securityService.IsEmailIDAvailabel(Model.Email))
            {
                var PWS = SeService.RandomString();

                var PW = CryptorEngine.Encrypt(PWS, true);
                var user = new User
                               {
                                   DateCreated = DateTime.UtcNow,
                                   DateLastActivity = DateTime.UtcNow,
                                   DateLastPasswordChange = DateTime.UtcNow,
                                   Email = Model.Email,
                                   DateLastLogin = DateTime.UtcNow,
                                   IsActive = false,
                                   FirstName = Model.Email,
                                   LastName = "",
                                   Password = PW,
                                   UserName = Model.Email
                               };
                _securityService.CreateUser(user);
                var ver_log = new EmailVerificationlLog()
                {
                    UserId = user.Id,
                    VerifiedId = guid,
                    CreateDate = DateTime.UtcNow
                };
                _VerificationlLogRepositories.Add(ver_log);
            }
            return Content("<i class='icon-ok'></i> The link to access My Ads has been emailed to you.");
        }


        public ActionResult myadsindex(string UN)
        {
            var log = _VerificationlLogRepositories.GetById(x => x.VerifiedId == UN);
            if (log != null)
            {
                var user = _securityService.GetUserById(log.UserId);
                AuthenticationService.SignIn(user, false);
                //FormsAuthentication.SetAuthCookie(user.UserName, false /* createPersistentCookie */);
                return RedirectToAction("MyAds", "Home");
            }
            return RedirectToAction("Index", "Home");
        }
        

        #region Status Codes
        private static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // See http://go.microsoft.com/fwlink/?LinkID=177550 for
            // a full list of status codes.
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "User name already exists. Please enter a different user name.";

                case MembershipCreateStatus.DuplicateEmail:
                    return "A user name for that e-mail address already exists. Please enter a different e-mail address.";

                case MembershipCreateStatus.InvalidPassword:
                    return "The password provided is invalid. Please enter a valid password value.";

                case MembershipCreateStatus.InvalidEmail:
                    return "The e-mail address provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidAnswer:
                    return "The password retrieval answer provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidQuestion:
                    return "The password retrieval question provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidUserName:
                    return "The user name provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.ProviderError:
                    return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                case MembershipCreateStatus.UserRejected:
                    return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                default:
                    return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
            }
        }
        #endregion
    }
}
